package com.hzbank.knowledgebase.view;

import android.content.Context;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.util.AttributeSet;
import android.util.Size;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.TextureView;

import androidx.annotation.NonNull;

import com.hzbank.knowledgebase.utils.Utils;

import org.json.JSONObject;

import java.io.Serializable;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

public class KdbMp4Renderder extends TextureView implements TextureView.SurfaceTextureListener {

    private MediaPlayer mediaPlayer;

    private Surface splashSurface;
    private SurfaceTexture splashSurfaceTexture;

    private Uri videoUri;
    private String videoName;

    private volatile boolean isPlaying = false;
    private Disposable playDisposable = null;
    //视频广告超5秒没播放，则直接跳转到首页
    private Disposable playTimeOutDisposable = null;


    private PlayerCallback playerCallback;

    public KdbMp4Renderder(Context context) {
        this(context, null);
    }

    public KdbMp4Renderder(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public KdbMp4Renderder(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //this.setOpaque(true);
    }

    private void initPlayer(){

        try{
            KdbMp4Renderder.this.setSurfaceTextureListener(this);
            mediaPlayer = new MediaPlayer();

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public void cancelPayer(){
        stopPlayer();
        this.isPlaying = false;
        stopTexture(this.splashSurfaceTexture);
    }

    public void setVideo(@NonNull Uri uri, String videoName) {

        try{

            initPlayer();

            //Utils.getDefault().showLog("视频广告数据="+ ((null==jsonObject) ? "为空" :JSON.toJSONString(jsonObject)));

            this.videoUri = uri;
            this.videoName = videoName;

            //2秒后如果还没播放需要判断是不是没有onSurfaceTextureAvailable回调

            playerTimeOut();

            playDisposable = Observable.timer(1, TimeUnit.SECONDS)
                    .subscribeOn(Schedulers.io())
                    .observeOn(Schedulers.io())
                    .subscribe(new Consumer<Long>() {
                        @Override
                        public void accept(Long aLong) throws Exception {

                            if(null!=playDisposable){
                                playDisposable.dispose();
                                playDisposable = null;
                            }

                            if(!isPlaying){

                                if(KdbMp4Renderder.this.isAvailable()){

                                    if(!isPlaying) player(KdbMp4Renderder.this.getSurfaceTexture());

                                    Utils.getDefault().showLog("视频广告-兼容模式播放");
                                }

                            }

                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) throws Exception {

                            if(null!=playDisposable){
                                playDisposable.dispose();
                                playDisposable = null;
                            }

                            if(!isPlaying){

                                if(KdbMp4Renderder.this.isAvailable()){

                                    if(!isPlaying) player(KdbMp4Renderder.this.getSurfaceTexture());

                                    Utils.getDefault().showLog("视频广告-兼容模式播放");

                                }
                            }

                        }
                    });


        }catch (Exception e){
            e.printStackTrace();

            if(null!= KdbMp4Renderder.this.playerCallback) KdbMp4Renderder.this.playerCallback.playError((e == null) ? "setVideoJsonObject-播放组件不可用" : "setVideoJsonObject-" +e.getMessage());

        }
    }

    private void playerTimeOut(){

        //此处异常，尝试3次，如果3次还是组件不可用，则直接按播放失败处理

        playTimeOutDisposable = Observable.timer( 5, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {

                        if(null!=playTimeOutDisposable){
                            playTimeOutDisposable.dispose();
                            playTimeOutDisposable = null;
                        }
                        if(null!= KdbMp4Renderder.this.playerCallback) KdbMp4Renderder.this.playerCallback.playError("setVideoJsonObject-播放超时");

                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {

                        if(null!=playTimeOutDisposable){
                            playTimeOutDisposable.dispose();
                            playTimeOutDisposable = null;
                        }
                        if(null!= KdbMp4Renderder.this.playerCallback) KdbMp4Renderder.this.playerCallback.playError("setVideoJsonObject-播放超时");
                    }
                });


    }

    public void setMute(boolean isMute){
        try{

            if(isMute){
                mediaPlayer.setVolume(0f, 0f);
            } else {
                mediaPlayer.setVolume(1f, 1f);
            }
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    public synchronized void player(SurfaceTexture surface){
        try {

            if(null!=playTimeOutDisposable){
                playTimeOutDisposable.dispose();
                playTimeOutDisposable = null;
            }

            if(null == surface){

                if(null!= KdbMp4Renderder.this.playerCallback) KdbMp4Renderder.this.playerCallback.playError("player - surface为空");
                return;
            }

            if(isPlaying){

                return;
            }

            isPlaying = true;

            this.splashSurfaceTexture = surface;

            this.splashSurface = new Surface(this.splashSurfaceTexture);

            mediaPlayer.reset();//重置

            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

            setMute(false);

            if(null == videoUri || !Utils.getDefault().kdbVideoExists(this.videoName)){


                if(null!= KdbMp4Renderder.this.playerCallback) KdbMp4Renderder.this.playerCallback.playError("player - 视频文件不存在");

            }else {

                mediaPlayer.setDataSource(getContext(), videoUri);
            }

            mediaPlayer.setSurface(this.splashSurface);

            mediaPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);

            mediaPlayer.prepare();

            mediaPlayer.start();
            mediaPlayer.setLooping(false);

//            mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
//                @Override
//                public void onPrepared(MediaPlayer mp) {
//
//                    //开始播放回调
//                    if(null!=SplashVideView.this.splashPlayerCallback) SplashVideView.this.splashPlayerCallback.playStart();
//
//
//                }
//            });

            mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                @Override
                public boolean onError(MediaPlayer mp, int what, int extra) {

                    try{


                        Utils.getDefault().showLog("开始视频播放异常-what"+what+"--extra="+extra);

                        //异常回调
                        if(null!= KdbMp4Renderder.this.playerCallback) KdbMp4Renderder.this.playerCallback.playError("setOnErrorListener--播放异常-what"+what+"--extra="+extra);

                    }catch (Exception e){
                        e.printStackTrace();

                        //异常回调
                        if(null!= KdbMp4Renderder.this.playerCallback) KdbMp4Renderder.this.playerCallback.playError("setOnErrorListener--播放异常-exception="+(null == e ? "" : e.getMessage()));
                    }

                    return false;
                }
            });

            mediaPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
                @Override
                public boolean onInfo(MediaPlayer mp, int what, int extra) {

                    try{

                        Utils.getDefault().showLog("开屏视频广告播放-setOnInfoListener-what="+what+"--extra="+extra);

                        if(what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START
                                || what == MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING){
                            //回调视频时长 ms
                            if(null!= KdbMp4Renderder.this.playerCallback) KdbMp4Renderder.this.playerCallback.videoDuration();
                        } else {

                            //播放异常
                            if(null!= KdbMp4Renderder.this.playerCallback) KdbMp4Renderder.this.playerCallback.playError("setOnInfoListener-what="+what+"--extra="+extra);
                        }

                    }catch (Exception e){
                        e.printStackTrace();

                        //播放异常
                        if(null!= KdbMp4Renderder.this.playerCallback) KdbMp4Renderder.this.playerCallback.playError("setOnInfoListener-exception="+(null == e ? "" : e.getMessage()));
                    }
                    return false;
                }
            });

            mediaPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
                @Override
                public void onBufferingUpdate(MediaPlayer mp, int percent) {
                    //BLogger.getDefault().log("开屏视频广告播放-onBufferingUpdate-percent="+percent);
                }
            });

            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {

                    try{

                        //播放完成回调
                        if(null!= KdbMp4Renderder.this.playerCallback) KdbMp4Renderder.this.playerCallback.playCompletion();

                    } catch (Exception e){
                        e.printStackTrace();

                        //播放异常
                        if(null!= KdbMp4Renderder.this.playerCallback) KdbMp4Renderder.this.playerCallback.playError("setOnCompletionListener-exception="+(null == e? "" : e.getMessage()));
                    }
                }
            });

        } catch (Exception e) {
            e.printStackTrace();

            Utils.getDefault().showLog("开始视频播放异常="+((null == e) ? "无异常信息" : e.getMessage()));

            if(null!= KdbMp4Renderder.this.playerCallback) KdbMp4Renderder.this.playerCallback.playError("player - 异常"+((null == e) ? "无异常信息" : e.getMessage()));
        }
    }

    public void setPlayerCallback(PlayerCallback playerCallback) {
        this.playerCallback = playerCallback;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                return true;
            case MotionEvent.ACTION_UP:

                if(null!=this.playerCallback) this.playerCallback.videoSikp(inClickArea(event.getRawX(), event.getRawY()));

                break;
        }

        return super.onTouchEvent(event);
    }

    private boolean inClickArea(float rawX, float rawY){

        //判断 x, y 坐标是否在指定区域

        Utils.getDefault().showLog("视频广告点击坐标 -- x="+rawX +"-- y="+rawY);

        try{

            //设置可点击区域
            RectF canClickArea = new RectF();
            Size realResolution = Utils.getDefault().getRealResolution(getContext());
            canClickArea.left = 100F;
            canClickArea.right = (float) realResolution.getWidth() - 100F;
            canClickArea.top = (float) (realResolution.getHeight() * 3) / (float)4;
            canClickArea.bottom = (float) realResolution.getHeight();

            return canClickArea.contains(rawX, rawY);

        }catch (Exception e){
            e.printStackTrace();
        }

        return false;

    }

    private void stopPlayer(){

        try{

            if (mediaPlayer != null) {

                mediaPlayer.setLooping(false);
                mediaPlayer.stop();
                mediaPlayer.reset();
                mediaPlayer.release();

                mediaPlayer = null;
            }

        }catch (Exception e){
            e.printStackTrace();
        }

    }

    public void pause(){
        //暂停
        try{

            this.mediaPlayer.pause();

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public void replay(){
        //重新播放
        try{

            this.mediaPlayer.start();

            this.playerCallback.videoReplay();

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public void seekToHandle(int progress){

        try{

            this.mediaPlayer.seekTo(progress);

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public int getVideoDuration(){

        try{

            return this.mediaPlayer.getDuration();

        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }
    }

    public int getCurrentVideoPosition(){

        try{

            return this.mediaPlayer.getCurrentPosition();

        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }
    }

    private void stopTexture(@NonNull SurfaceTexture surface){

        try{
            surface.release();
            surface = null;
            this.splashSurface = null;
            this.splashSurface.release();

            if(null!=playDisposable){
                playDisposable.dispose();
                playDisposable = null;
            }

            if(null!=playTimeOutDisposable){
                playTimeOutDisposable.dispose();
                playTimeOutDisposable = null;
            }

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//        try{
//
//            int videoWidth = Utils.getDefault().getScreenSize(getContext()).getWidth();
//
//            //高度根据是否是全面屏来判断
//            //全面屏-getScreenRealHeight
//            //存在虚拟按键 - 高度要去掉虚拟按键高度（华为可以设置虚拟导航栏，非全面屏）
//
//            int videoHeight = Utils.getDefault().getScreenSize(getContext()).getHeight();
//
//            setMeasuredDimension(videoWidth, videoHeight);
//
//        }catch (Exception e){
//            e.printStackTrace();
//
//            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//        }

    }

    @Override
    public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surface, int width, int height) {

        try{

            Utils.getDefault().showLog("开始视频播放异常=onSurfaceTextureAvailable1");

            if(null!=playDisposable){
                playDisposable.dispose();
                playDisposable = null;
            }

            if(!isPlaying) player(surface);

        }catch (Exception e){
            e.printStackTrace();
            Utils.getDefault().showLog("开始视频播放异常=onSurfaceTextureAvailable2"+((null == e)? "无异常信息" : e.getMessage()));

            //异常回调
            if(null!= KdbMp4Renderder.this.playerCallback) KdbMp4Renderder.this.playerCallback.playError("onSurfaceTextureAvailable--异常-"+((null == e)? "无异常信息" : e.getMessage()));
        }
    }

    @Override
    public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width, int height) {
        Utils.getDefault().showLog("开始视频播放异常=onSurfaceTextureSizeChanged");
    }

    @Override
    public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) {

        Utils.getDefault().showLog("开始视频播放异常=onSurfaceTextureDestroyed");
        stopTexture(surface);
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {
        Utils.getDefault().showLog("开始视频播放异常=onSurfaceTextureUpdated");
    }

    public static interface PlayerCallback{

        //void playStart();
        void playError(String reason);

        void playCompletion();

        void videoDuration();

        void videoSikp(boolean canSkip);

        void videoReplay();
    }

    public static class SplashVideoInfo implements Serializable {

        public String duration; //视频时长，毫秒
        public String mime; //视频文件mime
        public String rotation; //视频方向
        public String width; //视频宽度
        public String hight; //视频高度


    }
}